package main

import (
	"fmt"
	"reflect"
)

type Monster struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Score float32
	Sex   string
}

func (monster Monster) Print() {
	fmt.Printf("-------start------ \n")
	fmt.Printf("monster ----> %v \n", monster)
	fmt.Printf("-------end-------- \n")

}

func (monster Monster) GetSum(num1, num2 int) int {
	return num1 + num2
}

func (monster Monster) set(name string, age int, score float32, sex string) {
	monster.Name = name
	monster.Age = age
	monster.Score = score
	monster.Sex = sex
}

func TestStruct(a interface{}) {
	vType := reflect.TypeOf(a)
	vVale := reflect.ValueOf(a)
	vKind := vVale.Kind()

	if vKind != reflect.Struct {
		fmt.Println("expect struct")
		return
	}

	num := vVale.NumField()
	fmt.Printf("struct has %d fields \n", num)

	for i := 0; i < num; i++ {
		fmt.Printf("filed %d 的值为：%v \n", i, vVale.Field(i))
		//获取到struct标签，注意需要通过reflect,type来获取tag标签的值
		tagVal := vType.Field(i).Tag.Get("json")
		if tagVal != "" {
			fmt.Printf("filed %d,tag 为：%v \n", i, tagVal)
		}
	}

	numOfMethod := vVale.NumMethod()
	fmt.Printf("struct has %d method \n", numOfMethod)
	vVale.Method(1).Call(nil)

	//调用结果体的第1个方法Method(0)
	var params []reflect.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(40))
	res := vVale.Method(0).Call(params)     //传入的参数是[]reflect.Value
	fmt.Printf("res = %v \n", res[0].Int()) //返回结果，结果是 []reflect.Value

}

func main() {
	var a Monster = Monster{
		Name:  "黄鼠狼精",
		Age:   400,
		Score: 30.8,
		Sex:   "公",
	}

	TestStruct(a)
}
